#ifndef CAIPIAO_H_INCLUDED
#define CAIPIAO_H_INCLUDED

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <time.h>

#define CAIPIAOFILE  "Caipiao.txt"
#define LUCKYNUMBERSFILE  "LuckyNumbers.txt"

//#define DEBUG

#define U8 unsigned int
#define U16 unsigned long int
#define U64 unsigned long long

#define FREEP(p, n) \
        for(i=0; i<n; i++) {\
            free(p);\
            p++;\
        }

// Range of numbers.
static enum NumberRange {
    TWOTWOTWO = 0,      //222
    ONETWOTHREE,        //123
    ONETHREETWO,        //132
    THREEONETWO,        //312
    THREETWOONE,        //321
    TWOONETHREE,        //213
    TWOTHREEONE,        //231
    FOURONEONE,         //411
    ONEFOURONE,         //141
    ONEONEFOUR,         //114
    THREETHREEO = 10,   //330
    THREEOTHREE,        //303
    OTHREETHREE,        //033
    OFOURTWO,           //042
    TWOFOURO,           //240
    FOURTWOO,           //420
    FOUROTWO,           //402
    TWOOFOUR,           //204
    OTWOFOUR,           //024
    FIVEOONE,           //501
    ONEOFIVE = 20,      //105
    ONEFIVEO,           //150
    OONEFIVE,           //015
    FIVEONEO,           //510
    OFIVEONE,           //051
    OOSIX,              //006
    SIXOO,              //600
    OSIXO,              //060
};

static enum  ParityRatio {
    THREETOTHREE = 0, // 3:3
    FOURTOTWO,        // 4:2
    TWOTOFOUR,        // 2:4
    FIVETOONE,        // 5:1
    ONETOFIVE,        // 1:5
    SIXTOO,           // 6:0
    OTOSIX,           // 0:6

    OTOO,             // 0:0
};

static enum MESSAGE{
    HELLOMESSAGE = 0,
    FIRSTFUNCMESSAGE,
    DEFAULTMSG,
};

static enum FUNCCHOOSE{
    EXITFUNCTIONLIST = 0,
    AUTOUPDATEDATABASE,
    UPDATEDATABASEBYHAND,
    SEARCHASTAGE,
    CACULATEBESTGROUPS,
};

typedef struct OneStageNumbers{
    int Num[8];
};

typedef struct GetNumberNearLastStageNumber{
    int Num[12];
}GetNumberNearLastStageNumber;

typedef struct GroupList{
    int Ball[7];
    struct GroupList *next;
}GroupList;

/**
 * Near number from last stage.
 */
typedef struct NearNumberList{
    int num;
    struct NearNumberList *next;
}NearNumberList;

/**
 * FILE *FCP  a file pointer contains every stage numbers.
 */
static FILE *CPP;
int **ArrAllGroup;

U16 GlobalAllGroupsN;
static int *GlobalArrSaveStage;
// list after filter hot and cold number
GroupList *GroupListAfterFilterHotNumber;
GroupList *GroupListAfterFilterColdNumber;
// list after filter last stage's lucky number
GroupList *GroupListAfterFilterNearLastStage;
// list after filter courage & tow yard in lucky number
GroupList *GroupListAfterFilterCourageYard;
// list after filter ranges
GroupList *GroupListAfterFilterRanges;
// list after filter interval number
GroupList *GroupListAfterFilterIntervalNumber;
// list after filter AC value
GroupList *GroupListAfterFilterACValue;
// list after filter parity ratio
GroupList *GroupListAfterFilterParityRatio;
// list after filter mantissa same number
GroupList *GroupListAfterFilterMantissaSameNumber;
// list after filter sum value
GroupList *GroupListAfterFilterSumValue;
// list after filter sum value
GroupList *GroupListAfterFilterConsecutiveNumber;
// list after filter re No.
GroupList *GroupListAfterFilterReNo;
// list after filter size ratio.
GroupList *GroupListAfterFilterSizeRatio;
// list after filter Maxinum Re-number.
GroupList *GroupListAfterFilterMaxinumReNumber;

// write end list to file. File name generate by current time
time_t curTime;
struct tm *timeInfo;
char saveTime[12];

// Array of hot or cold number's number
int HotColdNumberN[33];
int *HotNumber, *ColdNumber;
// list of numbers near last stage's lucky number.
NearNumberList *getNearNumber;
GetNumberNearLastStageNumber NumberNearLastStageNumber;

/**
 * Functions.
 */
 // file operations.
int FileOpen(char *file);
int FileClose(FILE *FileP);
FILE* OpenAFile(char *FileName, char *OpenMethod);
static int WriteToFile(FILE *WriteToFileP, int *ArrNum);
static struct OneStageNumbers* ReadOneLineFromFile(FILE *WriteToFileP);
int FilterLastStageNumber(); // ling hao guolv

// function operations.
int GenerateAllGroup(U16 redN, U16 blueN);
static int* GetAllStages();
int CalculateBestGroups();

void showAllStageRange();
// show the interval of stages before.
void showIntervalStagesbefore();
// get one group's number's range
int getRange(GroupList *group);
// get one group's ac value
int getACValue(GroupList *group);
void showACValue();
// get one group's same number of mantissa
int getSameNumberOfMantissa(GroupList *group);
void showSameNumberOfMantissa();
// get and show sum
int getSum(GroupList *group);
void showSum();
// get and show consecutive number
void showConsecutiveNumber();
int getConsecutiveNumber(GroupList *group);
// size ratio
int getBigToSmall(GroupList *group);
void showBigToSmall();
// re-Number
int getReNo(GroupList numListPre, GroupList numList);
void showReNo();
// maxinum re-Number
int getMaxinumReNumber(GroupList *group, int stage);
void showMaxinumReNumber();

void GenerateHotColdNumber();
int NumberRangeCalculate(int Ball1, int ball2, int ball3, int ball4, int ball5, int ball6);

// other operations.
int UpdateDatabaseAutomatically();
int UpdateDatabaseHandly();

#endif // CAIPIAO_H_INCLUDED
